import sys
import subprocess
import tkinter as tk
from tkinter import ttk, messagebox

# 检查并安装必要的库
def install_required_packages():
    required = ['pyautogui']
    for package in required:
        try:
            __import__(package)
        except ImportError:
            try:
                subprocess.check_call([sys.executable, "-m", "pip", "install", package])
            except:
                messagebox.showerror("错误", f"无法安装必要的库：{package}\n请手动运行: pip install {package}")
                sys.exit(1)

# 安装依赖
install_required_packages()

# 导入其他库
import pyautogui
from threading import Thread
import time
import os

class AutoClickerApp:
    def __init__(self):
        # 主窗口
        self.root = tk.Tk()
        self.root.title("自动点击器")
        self.root.geometry("300x400")
        self.root.resizable(False, False)
        
        # 初始化变量 - 移到前面
        self.click_interval = tk.DoubleVar(value=0.1)
        self.total_clicks = tk.IntVar(value=0)
        self.is_running = False
        
        # 设置窗口图标
        try:
            # 获取脚本所在目录
            if getattr(sys, 'frozen', False):
                application_path = sys._MEIPASS
            else:
                application_path = os.path.dirname(os.path.abspath(__file__))
                
            icon_path = os.path.join(application_path, "icon.ico")
            if os.path.exists(icon_path):
                self.root.iconbitmap(icon_path)
        except:
            pass
        
        # 创建悬浮按钮
        self.floating_button = FloatingButton(self)
        
        # 创建控制面板
        self.create_control_panel()
        
        # 添加错误处理
        self.root.report_callback_exception = self.show_error

    def show_error(self, exc_type, exc_value, exc_traceback):
        """显示错误信息"""
        error_msg = f"发生错误：\n{exc_type.__name__}: {exc_value}"
        messagebox.showerror("错误", error_msg)

    def create_control_panel(self):
        # 样式设置
        style = ttk.Style()
        style.configure('TFrame', padding=10)
        style.configure('TLabel', padding=5)
        style.configure('TButton', padding=5)
        
        # 主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 状态显示
        status_frame = ttk.LabelFrame(main_frame, text="状态", padding=10)
        status_frame.pack(fill=tk.X, pady=5)
        
        self.status_label = ttk.Label(status_frame, text="就绪")
        self.status_label.pack()
        
        self.click_count_label = ttk.Label(status_frame, text="点击次数: 0")
        self.click_count_label.pack()
        
        # 设置区域
        settings_frame = ttk.LabelFrame(main_frame, text="设置", padding=10)
        settings_frame.pack(fill=tk.X, pady=5)
        
        # 点击间隔设置
        interval_frame = ttk.Frame(settings_frame)
        interval_frame.pack(fill=tk.X)
        
        ttk.Label(interval_frame, text="点击间隔(秒):").pack(side=tk.LEFT)
        interval_entry = ttk.Entry(interval_frame, textvariable=self.click_interval, width=10)
        interval_entry.pack(side=tk.LEFT, padx=5)
        
        # 快捷键说明
        hotkey_frame = ttk.LabelFrame(main_frame, text="快捷键", padding=10)
        hotkey_frame.pack(fill=tk.X, pady=5)
        
        ttk.Label(hotkey_frame, text="空格键: 开始点击").pack()
        ttk.Label(hotkey_frame, text="右键: 停止点击").pack()
        ttk.Label(hotkey_frame, text="ESC: 退出程序").pack()
        
        # 控制按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=10)
        
        ttk.Button(button_frame, text="显示/隐藏指示器", 
                  command=self.toggle_indicator).pack(side=tk.LEFT, expand=True, padx=5)
        ttk.Button(button_frame, text="退出程序",
                  command=self.quit_app).pack(side=tk.LEFT, expand=True, padx=5)

    def toggle_indicator(self):
        if self.floating_button.root.winfo_viewable():
            self.floating_button.root.withdraw()
        else:
            self.floating_button.root.deiconify()

    def update_status(self, status_text):
        self.status_label.config(text=status_text)
        
    def update_click_count(self, count):
        self.click_count_label.config(text=f"点击次数: {count}")
        
    def quit_app(self):
        try:
            if hasattr(self, 'floating_button'):
                self.floating_button.on_closing()
            self.root.quit()
        except:
            sys.exit(0)
        
    def run(self):
        try:
            # 设置DPI感知
            try:
                from ctypes import windll
                windll.shcore.SetProcessDpiAwareness(1)
            except:
                pass
            
            self.root.mainloop()
        except KeyboardInterrupt:
            self.quit_app()

class FloatingButton:
    def __init__(self, app):
        self.app = app
        self.root = tk.Toplevel(app.root)
        self.root.overrideredirect(True)
        self.root.attributes('-topmost', True)
        self.root.attributes('-transparentcolor', 'black')
        self.root.attributes('-alpha', 0.7)
        
        # 创建画布
        self.button = tk.Canvas(self.root, width=26, height=26, bg='black',
                              highlightthickness=0)
        self.create_beautiful_circle('red')
        self.button.pack()
        
        # 初始化变量
        self.clicking = False
        self.click_thread = None
        self.click_count = 0
        self.click_interval = app.click_interval  # 保存对主窗口点击间隔变量的引用
        
        # 绑定事件
        self.button.bind('<Button-1>', self.start_move)
        self.button.bind('<B1-Motion>', self.on_move)
        self.root.bind('<space>', self.start_clicking)
        self.root.bind('<Button-3>', self.stop_clicking)
        
        # 设置初始位置
        self.root.geometry('+100+100')
        
        # 添加退出处理
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.root.bind('<Control-c>', self.on_closing)
        self.root.bind('<Escape>', self.on_closing)

    def start_move(self, event):
        self.x = event.x
        self.y = event.y

    def on_move(self, event):
        deltax = event.x - self.x
        deltay = event.y - self.y
        x = self.root.winfo_x() + deltax
        y = self.root.winfo_y() + deltay
        self.root.geometry(f'+{x}+{y}')

    def create_beautiful_circle(self, color):
        self.button.delete("all")
        self.button.create_oval(1, 1, 25, 25, fill=color, outline=color)
        
        highlight_color = '#ff6666' if color == 'red' else '#66ff66'
        self.button.create_oval(5, 5, 21, 21, fill=highlight_color, outline=highlight_color)
        self.button.create_oval(8, 7, 13, 12, fill='white', outline='white', stipple='gray50')

    def auto_click(self):
        while self.clicking:
            try:
                current_x = self.root.winfo_x()
                current_y = self.root.winfo_y()
                
                self.root.withdraw()
                time.sleep(0.05)
                
                click_x = current_x + 13
                click_y = current_y + 13
                
                pyautogui.click(x=click_x, y=click_y, button='left')
                
                self.root.deiconify()
                self.root.geometry(f'+{current_x}+{current_y}')
                
                self.click_count += 1
                self.app.update_click_count(self.click_count)
                self.root.update()
                
                interval = self.click_interval.get()
                time.sleep(float(interval))
            except Exception as e:
                self.root.deiconify()
                self.app.show_error(type(e), str(e), None)
                break

    def start_clicking(self, event):
        if not self.clicking:
            self.clicking = True
            self.create_beautiful_circle('green')
            self.app.update_status("正在点击")
            self.click_thread = Thread(target=self.auto_click)
            self.click_thread.daemon = True
            self.click_thread.start()

    def stop_clicking(self, event):
        if self.clicking:
            self.clicking = False
            self.create_beautiful_circle('red')
            self.app.update_status("已停止")
            print(f"本次共点击了 {self.click_count} 次")
            self.click_count = 0
            self.app.update_click_count(0)

    def on_closing(self, event=None):
        self.clicking = False
        self.root.destroy()

if __name__ == '__main__':
    # 启用自动防故障功能
    pyautogui.FAILSAFE = True
    
    try:
        app = AutoClickerApp()
        app.run()
    except Exception as e:
        messagebox.showerror("错误", f"程序运行失败：{str(e)}")
        sys.exit(1) 